package com.nullpointer.playerinfo.bungee;

import java.sql.SQLException;
import java.util.List;
import java.util.UUID;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.jdbc.DataSourceConnectionSource;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import com.nullpointer.playerinfo.common.objects.Player;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class Mysql {
    final String host;
    final int port;
    final String database;
    final String username;
    final String password;

    ConnectionSource connectionSource;
    Dao<Player, UUID> playerDao;

    public Mysql(String host, int port, String database, String username, String password) {
        this.host = host;
        this.port = port;
        this.database = database;
        this.username = username;
        this.password = password;
    }

    public void connect() {
        if (connectionSource != null || playerDao != null) return;

        String url = "jdbc:mysql://" + host + ":" + port + "/" + database + "?useSSL=false";

        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(url);
        config.setUsername(username);
        config.setPassword(password);
        //解决8小时mysql断连问题
        config.setMaxLifetime(28600000); //设置连接最大生命周期
        config.setConnectionTestQuery("SELECT 1"); //心跳检查
        config.setIdleTimeout(60000); //60秒检查一次
        //其他优化配置
        config.setMaximumPoolSize(5); // 最大连接数
        config.setMinimumIdle(1); // 最小空闲连接数
        config.setConnectionTimeout(10000); // 获取连接的超时时间

        HikariDataSource hikariDataSource = new HikariDataSource(config);

        try {
            connectionSource = new DataSourceConnectionSource(
                hikariDataSource, 
                hikariDataSource.getJdbcUrl()
            );

            playerDao = DaoManager.createDao(connectionSource, Player.class);
            TableUtils.createTableIfNotExists(connectionSource, Player.class);
        } catch(SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public void disConnect() {
        if (connectionSource != null) {
            connectionSource.closeQuietly();
            connectionSource = null;
            playerDao = null;
        }
    }

    public Player getPlayer(UUID playerUUID) throws SQLException {
        return playerDao.queryForId(playerUUID);
    }

    public Player getPlayer(String playerName) throws SQLException {
        List<Player> resultList = playerDao.queryForEq("name", playerName);
        if (resultList.size() == 1) {
            return resultList.get(0);
        } else {
            return null;
        }
    }

    public void savePlayer(Player player) throws SQLException {
        playerDao.createOrUpdate(player);
    }

    public Boolean havePlayer(UUID playerUUID) throws SQLException {
        if (playerDao.queryForId(playerUUID) == null) {
            return false;
        }
        return true;
    }
}
